import Singleton from "../context/Singleton";
import { DataType } from "../db/DataType";
import LocalDb from "../db/LocalDb";
import Utils from "../utils/Utils";
import { SoundOption } from "./SoundItem";
import { SoundTypeItem, SoundTypeOption } from "./SoundTypeItem";

export default class SoundManage extends Singleton {
    public static get I() { return this.Instance() }

    private _items = new Map<number, SoundTypeItem>();

    /**
     * 播放音效
     * @param type 0 背景音乐（背景音乐不要用其它类型底层技术不一样）
     * @param url 
     * @param opt 
     */
    play(url: string, type?: number, opt?: SoundOption) {
        type = type == null ? 0 : type;
        let elm = this._items.get(type);
        if (Utils.isNil(elm)) {
            elm = new SoundTypeItem(type, this.getOpt(type));
            this._items.set(type, elm);
        }
        elm.play(url, opt);
        elm.setVolume(this.systemVolume, this.getuseVolumeByType(type));
    }

    /**
     * 停止声音
     * @param type 
     * @param url 声音文件，是null时停止所有
     * @returns 
     */
    stop(type: number, url?: string) {
        let elm = this.getItem(type);
        if (!elm) return;
        Utils.isNil(url) ? elm.stopAll() : elm.stop(url);
    }

    getItem(type: number) {
        let elm = this._items.get(type);
        return elm;
    }

    updateVolume() {
        this._items.forEach((v, k) => v.setVolume(this.systemVolume, this.getuseVolumeByType(k)))
    }

    getuseVolumeByType(type: number) {
        let v = LocalDb.Instance().getItem(DataType.VOLUME_TYPE, type + "");
        return v == null ? 100 : v;
    }

    /**设置某一个type的音量，用户自定义 */
    setuseVolumeByType(type: number, v: number) {
        let oldV = this.getuseVolumeByType(type);
        if (oldV != v) {

            this.updateVolume();
        }
    }

    get systemVolume() {
        return LocalDb.Instance().getItemAsNum(DataType.VOLUME_SYSTEM) || 80;
    }

    /**设置基础音量，UI显示用 */
    set systemVolume(v: number) {
        let old = LocalDb.Instance().getItemAsNum(DataType.VOLUME_SYSTEM)
        if (old === v) return;

        LocalDb.Instance().setItem(DataType.VOLUME_SYSTEM, v);
        this.updateVolume();
    }

    private getOpt(t: number): SoundTypeOption {
        return {
            volume: 20,
            maxInstance: 3,
            interval: 0,
            replaceable: 0,

            supresses: []
        }
    }
}